package com.swyc.osschat.Test.LambdaTest.Controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.DoublePredicate;
import java.util.function.IntPredicate;
import java.util.function.LongPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.apache.shiro.util.CollectionUtils;

import com.google.common.collect.Lists;
import com.swyc.osschat.Test.LambdaTest.Bean.Student;

/**
 * 评估参数里面的表达式(说白了就是验证传进来的参数符不符合规则
 * 它的返回值是一个boolean类型
 * @author zhaol@yunrong.cn
 * @version V2.1
 * @since 2.1.0 2019/8/9 10:54
 * 与Predicate<T>相关的接口
 * BiPredicate<T, U>
 * 针对两个参数,看两个参数是否符合某个条件表达式
 * DoublePredicate
 * 看一个double类型的值是否符合某个条件表达式
 * IntPredicate
 * 看一个int类型的值是否符合某个条件表达式
 * LongPredicate
 * 看一个long类型的值是否符合某个条件表达式
 */
public class PredicateTest2 {
    public static void main(String[] args) {
        Predicate<List<Student>> predicate = x -> test(x);
        /** 增加判断条件(当添加多个条件的时候则会一个条件一个条件的判断，如果一个条件为false，那么后面的判断也不会执行) */
        predicate = predicate.and(x->testTwo(x));
        Predicate<List<Student>> predicate2 = x -> x.stream().anyMatch(e->test1(e));
        List<Student> student1 = null;
        List<Student> student2 = new ArrayList<>();
        List<Student> student3 = Lists.newArrayList();
        List<Student> student4 = Lists.newArrayList(new Student("张三",2,11));
        List<Student> students = Student.generateData();
        System.out.println(predicate.test(students));

        Predicate<String> predicate1 = new Predicate<String>() {
            @Override
            public boolean test(String s) {

                return s.equals("zhangsan");
            }
        };
        System.out.println(predicate1.test("张三"));
        System.out.println(predicate1.test("zhangsan"));
        /** 筛选数据(筛选出年龄大于25的student)negate否定，negate()方法表示筛选age<=25 */
        Predicate<Student> studentPredicate = x -> x.getAge() >23;
        List<Student> studentList = Student.generateData();
        List<Student> studentsNegate1 = studentList.stream().filter(studentPredicate.negate()).collect(Collectors.toList());
        long count1 = studentList.stream().filter(studentPredicate.negate()).count();
        /** 条件判断or */
        studentPredicate = studentPredicate.or(x -> x.getName().equals("李黑炭"));
        List<Student> studentsNegate2 = studentList.stream().filter(studentPredicate).collect(Collectors.toList());
        long count2 = studentList.stream().filter(studentPredicate).count();
        Student student = studentList.get(4);
        Predicate<Student> studentPredicate1 = x ->Objects.equals(x,student);
        List<Student> student5 = studentList.stream().filter(studentPredicate1).collect(Collectors.toList());
        /** BiPredicate */
        boolean result = compare((a, b) -> a / 2 == b, 10, 5);
        BiPredicate<Integer, Integer> biPredicate = (a, b) -> a .equals(b);
        System.out.println("Compare result: " + result + ";" + biPredicate.test(9,9));
        /** DoublePredicate */
        DoublePredicate doublePredicate = doub -> doub != 0;
        /** IntPredicate */
        IntPredicate intPredicate = inte -> inte == 100;
        /** LongPredicate */
        LongPredicate longPredicate = lon -> lon == 99;
        System.out.println(doublePredicate.test(10));
    }

    public static boolean test(List<Student> s){
        if (Objects.isNull(s)){
            return false;
        }
        return s.stream().allMatch(t->Objects.nonNull(t));
    }

    public static boolean testTwo(List<Student> s){
        if (CollectionUtils.isEmpty(s)){
            return false;
        }
        if (s.size()<5){
            return false;
        }
        return true;
    }

    public static boolean test1(Student s){
        return Objects.isNull(s);
    }

    public static boolean compare(BiPredicate<Integer, Integer> bi, Integer i1,
        Integer i2) {
        return bi.test(i1, i2);
    }
}
